const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'

class DDPromise {
  constructor(callback) {
    this.promiseStatus = PROMISE_STATUS_PENDING
    this.onFulfilledArr = []
    this.onRejectedArr = []
    const resolve = (value) => {
      if (this.promiseStatus === PROMISE_STATUS_PENDING) {
        console.log('resolve run, enter fulfilled status')
        //添加微任务
        queueMicrotask(() => {
          if (this.promiseStatus !== PROMISE_STATUS_PENDING) return
          this.promiseStatus = PROMISE_STATUS_FULFILLED
          this.value = value
          this.onFulfilledArr.forEach((onfulfilled) => {
            onfulfilled(this.value)
          })
        })
      }
    }
    const reject = (reason) => {
      if (this.promiseStatus === PROMISE_STATUS_PENDING) {
        console.log('reject run, enter rejected status')
        //添加微任务
        queueMicrotask(() => {
          if (this.promiseStatus !== PROMISE_STATUS_PENDING) return
          this.promiseStatus = PROMISE_STATUS_REJECTED
          this.reason = reason
          this.onRejectedArr.forEach((onreject) => {
            onreject(this.reason)
          })
        })
      }
    }
    callback(resolve, reject)
  }

  then(onFulfilled, onRejected) {
    if (this.promiseStatus === PROMISE_STATUS_FULFILLED && onFulfilled) {
      onFulfilled(this.value)
    }
    if (this.promiseStatus === PROMISE_STATUS_REJECTED && onRejected) {
      onRejected(this.reason)
    }
    if (this.promiseStatus === PROMISE_STATUS_PENDING) {
      //将成功回调和失败回调放到数组中
      this.onFulfilledArr.push(onFulfilled)
      this.onRejectedArr.push(onRejected)
    }
  }
}

const promise = new DDPromise((resolve, reject) => {
  console.log('DDPromise run')
  resolve('resolve msg...')
  reject('reject msg...')
})
promise.then(
  (res1) => {
    console.log('res1: ' + res1)
  },
  (err1) => {
    console.log('err1: ' + err1)
  }
)

promise.then(
  (res2) => {
    console.log('res2: ' + res2)
  },
  (err2) => {
    console.log('err2: ' + err2)
  }
)

//在确定Promise状态后再次调用then
setTimeout(() => {
  promise.then(
    (res) => {
      console.log('res3: ' + res)
    },
    (err) => {
      console.log('err3: ' + err)
    }
  )
}, 1000)
